ツールが未対応でもMFA & AssumeRoleしたい! aws-mfaを使って簡単に一時的な資格情報を生成してみた
aws-mfaって?
aws-mfaはOSS(MITライセンス)で公開されている、MFAが適用されている、AssumeRoleが必要なアカウントに対して使用するツールです。
AWS STSから一時的な資格情報を取得して、AWS資格情報ファイル(~/.aws/credentials)へ書き出しするプロセスを自動で行ってくれます。
broamski/aws-mfa: Manage AWS MFA Security Credentials
インストール
インストール方法は2通りあります。お好みの方法でインストールしてください。
pipを使ってインストール
pip install aws-mfa
リポジトリをクローンしてインストール
git clone https://github.com/broamski/aws-mfa cd ./aws-mfa python setup.py install
使い方
~/.aws/credentialsの設定
~/.aws/credentials に以下の様に設定します。
profile_nameは任意のプロファイル名を設定し、AWS_ACCESS_KEY,AWS_SECRET_ACCESS_KEYには自分のアカウントの資格情報を取得して設定してください。
対象のアカウントが、MFA適用でないならaws_mfa_deviceは指定する必要がありません。
[profile_name-long-term] aws_access_key_id = {AWS_ACCESS_KEY} aws_secret_access_key = {AWS_SECRET_ACCESS_KEY} aws_mfa_device = {AWS_MFA_DEVICE} assume_role = {ASSUME_ROLE}
arn:aws:iam::123456789012:mfa/tanaka.taro AWSアカウント番号は自分のアカウント番号です。(AssumeRole元)
arn:aws:iam::210987654321:role/tanaka.taro AWSアカウント番号は対象のアカウント番号です。(AssumeRole先)
資格情報の取得
資格情報を取得します。
aws-mfa --profile profile_name
ワンタイムパスワードの入力を求められるので入力します。
INFO - Validating credentials for profile: profile_name INFO - Short term credentials section profile_name is missing, obtaining new credentials. Enter AWS MFA code for device [arn:aws:iam::123456789012:mfa/tanaka.taro] (renewing for 3600 seconds):{OTP} INFO - Assuming Role - Profile: profile_name, Role: arn:aws:iam::210987654321:role/tanaka.taro, Duration: 3600 INFO - Success! Your credentials will expire in 3600 seconds at: 2018-05-16 12:37:48+00:00
~/.aws/credentials を確認すると資格情報が登録されています。
[profile_name] assumed_role = True assumed_role_arn = arn:aws:iam::210987654321:role/tanaka.taro aws_access_key_id = {AWS_ACCESS_KEY} aws_secret_access_key = {AWS_SECRET_ACCESS_KEY} aws_session_token = {AWS_SESSION_TOKEN} aws_security_token = {AWS_SECURITY_TOKEN} expiration = 2018-05-16 12:37:48
再度コマンドを実行すると、どうなるのでしょうか?試してみました。
aws-mfa --profile profile_name
取得中の認証情報がまだ有効であると表示されました。
INFO - Validating credentials for profile: profile_name with assumed role: arn:aws:iam::210987654321:role/tanaka.taro INFO - Your credentials are still valid for 3295.108415 seconds they will expire at 2018-05-16 12:37:48
さらに、意図的にexpiration を過去の日付に書き換えて実行してみました。
aws-mfa --profile profile_name
期限切れの場合は初回と同じように動作しました。
INFO - Validating credentials for profile: profile_name INFO - Short term credentials section profile_name is missing, obtaining new credentials. Enter AWS MFA code for device [arn:aws:iam::123456789012:mfa/tanaka.taro] (renewing for 3600 seconds):{OTP} INFO - Assuming Role - Profile: profile_name, Role: arn:aws:iam::210987654321:role/tanaka.taro, Duration: 3600 INFO - Success! Your credentials will expire in 3600 seconds at: 2018-05-16 12:44:39+00:00
~/.aws/credentials を確認すると資格情報が更新されていました!
オプションの紹介
aws-mfaには --profile 以外の複数のオプションがあります。
それぞれの使い方を紹介していきます。
--device
--device arn:aws:iam::123456788990:mfa/dudeman The MFA Device ARN. This value can also be provided via the environment variable 'MFA_DEVICE' or the ~/.aws/credentials variable 'aws_mfa_device'.
MFAデバイスを指定するオプションです。
環境変数 'MFA_DEVICE' または ~/.aws/credentials の aws_mfa_device を使用して指定することもできます。
MFA非適用のアカウントの場合は意識する必要がありません。
--duration
--duration DURATION The duration, in seconds, that the temporary credentials should remain valid. Minimum value: 900 (15 minutes). Maximum: 129600 (36 hours). Defaults to 43200 (12 hours), or 3600 (one hour) when using '--assume-role'. This value can also be provided via the environment variable 'MFA_STS_DURATION'.
取得する一時的な資格情報の有効期間を秒で指定するオプションです。
デフォルト値は43200(12時間)で、最小は900(15分) 最大は129600(36時間)です。
'--assume-role'を使用している場合、デフォルトが3600(1時間)になります。
環境変数 'MFA_STS_DURATION'を使用して指定することもできます。
--profile
--profile PROFILE If using profiles, specify the name here. The default profile name is 'default'. The value can also be provided via the environment variable 'AWS_PROFILE'.
~/.aws/credentials から読み込むプロファイル名を指定します。
デフォルトでは default がプロファイル名です。
環境変数 'AWS_PROFILE'を使用して指定することもできます。
--long-term-suffix
--long-term-suffix LONG_TERM_SUFFIX To identify the long term credential section by [<profile_name>-LONG_TERM_SUFFIX]. Use 'none' to identify the long term credential section by [<profile_name>]. Omit to identify the long term credential section by [<profile_name>-long-term].
~/.aws/credentials から読み込むプロファイル名のサフィックスを指定します。
指定しなければ、 {profile_name}-long-term が読み込まれます。
サフィックスなしにしたい場合は、 none で指定してください。
--short-term-suffix
--short-term-suffix SHORT_TERM_SUFFIX To identify the short term credential section by [<profile_name>-SHORT_TERM_SUFFIX]. Omit or use 'none' to identify the short term credential section by [<profile_name>].
~/.aws/credentials へ生成するプロファイル名のサフィックスを指定します。
指定しなければ、 {profile_name} で生成されます。
明示的にサフィックスなしにしたい場合は、 none で指定してください。
--assume-role
--assume-role arn:aws:iam::123456788990:role/RoleName The ARN of the AWS IAM Role you would like to assume, if specified. This value can also be provided via the environment variable 'MFA_ASSUME_ROLE'
AssumeRoleを指定するオプションです。
環境変数 'MFA_ASSUME_ROLE' または ~/.aws/credentials の assume_role を使用して指定することもできます。
AssumeRoleしないアカウントの場合は意識する必要がありません。
--role-session-name
--role-session-name ROLE_SESSION_NAME Friendly session name required when using --assume- role. By default, this is your local username.
AssumeRoleする際のロールセッション名を指定するオプションです。
指定しない場合は、ローカルユーザー名が使用されます。
AssumeRoleしないアカウントの場合は意識する必要がありません。
運用方法
direnvと組み合わせて使用しています。
aws-mfa --profile myproject --short-term-suffix dev aws-mfa --profile myproject --short-term-suffix stg aws-mfa --profile myproject --short-term-suffix prd
後は、ツール側でdevの時は myproject-devをstgの時はmyproject-stgを読み込むように設定します。
環境分けが不要な時は--short-term-suffixを外して、myprojectを読み込むように設定しています。
あとがき
このツールを知ったきっかけは、TerraformがAssumeRoleやMFA適用されたアカウント'単独'には対応しているが、AssumeRoleかつ元アカウトがMFA適用されている場合は動作しなかったからです。
TerraformのWorkspace機能を使って環境分けを行っており、なんとかしたいなとひたすらググり続けてたどり着きました。
AssumeRole、MFAの利用を肩代わりしてくれるイカしたツールです!(~/.aws/credentials から aws_session_token,aws_security_token を読み込むのに対応している必要はありますが)
このブログを書いている今 TerraformでMFA & AssumeRoleできるぞ!ってマサカリ飛んできそうで怖いですwでも、できるならぜひ知りたいです!